package controller

import (
	"mini_wms/app/model"

	"github.com/labstack/gommon/log"

	"github.com/tealeg/xlsx"

	"strconv"

	"time"

	"mini_wms/app/res"
)

type ProductBOM struct{
	Base
}

func NewProductBOM() *ProductBOM {
	return &ProductBOM{}
}

func (c *ProductBOM) GetProductBOMList(productCodeReq string) Res{
	log.Info("GetProductBOMList")
	log.Info("queryParam: " + productCodeReq)
	var listProductBOM []model.ProductBOM	
	var listProductManagement []model.ProductManagement
	var listPartManagement []model.PartManagement
	var listProductBOMRes [] res.ProductBOMRes
	if err := c.db().Where("del_flag = 0").Find(&listPartManagement).Error; err!= nil {
		c.log(err.Error())
		return c.error("未查询到零件数据")
	}

	if productCodeReq == "" {
		log.Info("GetProductBOMList productCodeReq is null")
		if err := c.db().Where("del_flag = 0").Order("create_time DESC").Find(&listProductManagement).Error; err!= nil {
			c.log(err.Error())
			return c.error("未查询到产品数据")
		}
	}else {
		productCode := "%" + productCodeReq + "%"
		log.Info("GetProductBOMList productCodeReq is " + productCode)
		if err := c.db().Where("del_flag = 0 and product_code LIKE?",productCode).Order("create_time DESC").Find(&listProductManagement).Error; err!= nil {
			c.log(err.Error())
			return c.error("未查询到产品数据")
		}
	}

	if err := c.db().Find(&listProductBOM).Error; err != nil {
		c.log(err.Error())
		return c.error("未查询到产品BOM数据")
	}
	productMap := make(map[int]model.ProductManagement)
	partMap := make(map[int]model.PartManagement)

	for _, product := range listProductManagement {
		productMap[product.ID] = product
	} 

	for _, part := range listPartManagement {
		partMap[part.ID] = part
	}

	for _, productBOM := range listProductBOM {
		var productBOMRes res.ProductBOMRes
		if product,ok := productMap[productBOM.ProductID]; ok {
			productBOMRes.ProductCode = product.ProductCode
			productBOMRes.ProductSku = product.ProductSku
		}else{
			continue
		}
		if part,ok := partMap[productBOM.PartID]; ok {
			productBOMRes.PartCode = part.PartCode
			productBOMRes.SkuName = part.SkuName
		}
		productBOMRes.PartQuantity = productBOM.PartQuantity
		listProductBOMRes = append(listProductBOMRes, productBOMRes)
	}
	return c.success(listProductBOMRes)
}

func (c *ProductBOM) ExportProductBOM() Res{
	log.Info("ExportProductBOM")
	var listProductBOM []model.ProductBOM
	var listProductManagement []model.ProductManagement
	var listPartManagement []model.PartManagement
	if err := c.db().Where("del_flag = 0").Find(&listPartManagement).Error; err!= nil {
		c.log(err.Error())
		return c.error("未查询到零件数据")
	}
	if err := c.db().Where("del_flag = 0").Find(&listProductManagement).Error; err!= nil {
		c.log(err.Error())
		return c.error("未查询到产品数据")
	}
	if err := c.db().Where("del_flag = 0").Find(&listProductBOM).Error; err != nil {
		c.log(err.Error())
		return c.error("未查询到产品BOM数据")
	}

	productMap := make(map[int]model.ProductManagement)
	partMap := make(map[int]model.PartManagement)

	for _, product := range listProductManagement {
		productMap[product.ID] = product
	} 

	for _, part := range listPartManagement {
		partMap[part.ID] = part
	}

	file := xlsx.NewFile()
	sheet, err := file.AddSheet("产品BOM")
	if err != nil {
		log.Error("ProductBOM Export Error:", err)
		return c.error(err.Error())
	}
	rowTitle := sheet.AddRow()
	cellProductCode := rowTitle.AddCell()
	cellProductCode.Value = "成品货号"
	cellProductSku := rowTitle.AddCell()
	cellProductSku.Value = "成品SKU"
	cellPartCode := rowTitle.AddCell()
	cellPartCode.Value = "零件货号"
	cellSkuName := rowTitle.AddCell()
	cellSkuName.Value = "零件SKU"
	cellPartQuantity := rowTitle.AddCell()
	cellPartQuantity.Value = "数量"
	cellCreateTime := rowTitle.AddCell()
	cellCreateTime.Value = "创建时间"
	for _, productBOM := range listProductBOM {
		row := sheet.AddRow()
		product,ok := productMap[productBOM.ProductID]
		if !ok {
			continue
		}
		part,ok := partMap[productBOM.PartID]
		if !ok {
			continue
		}

		cellProductCode := row.AddCell()
		cellProductCode.Value = product.ProductCode
		cellProductSku := row.AddCell()
		cellProductSku.Value = product.ProductSku
		cellPartCode := row.AddCell()
		cellPartCode.Value = part.PartCode
		cellSkuName := row.AddCell()
		cellSkuName.Value = part.SkuName
		cellPartQuantity := row.AddCell()
		cellPartQuantity.Value = strconv.Itoa(productBOM.PartQuantity)
		cellCreateTime := row.AddCell()
		cellCreateTime.Value = productBOM.CreateTime
	}
	appPath := c.pathExist(c.getAppPath() + "/outputFile")
	log.Info("appPath: ", appPath)
	file.Save(appPath + "/产品BOM报表.xlsx")
	return c.success(nil)
}

func  (c *ProductBOM) ImportProductBOM(filePath string) Res{
	log.Info("Import ProductBOM info: " + filePath)
	var listProductBOM []model.ProductBOM
	var listProductManagement []model.ProductManagement
	var listPartManagement []model.PartManagement
	if err := c.db().Where("del_flag = 0").Find(&listPartManagement).Error; err!= nil {
		c.log(err.Error())
		return c.error("未查询到零件数据")
	}
	if err := c.db().Where("del_flag = 0").Find(&listProductManagement).Error; err!= nil {
		c.log(err.Error())
		return c.error("未查询到产品数据")
	}
	if err := c.db().Find(&listProductBOM).Error; err != nil {

	}

	log.Info("Import ProductBOM partLen: " ,len(listPartManagement))
	log.Info("Import ProductBOM productLen: " ,len(listProductManagement))
	log.Info("Import ProductBOM productBOMLen: " ,len(listProductBOM))
	productMap := make(map[string]model.ProductManagement)
	partMap := make(map[string]model.PartManagement)
	productBOMMap := make(map[int]int)

	for _, product := range listProductManagement {
		productMap[product.ProductCode] = product
	} 

	for _, part := range listPartManagement {
		partMap[part.PartCode] = part
	}

	for _, productBOM := range listProductBOM {
		productBOMMap[productBOM.ProductID] = 1
	}

	xlFile, err := xlsx.OpenFile(filePath)
	if err != nil {
		return c.error(err.Error())
	}
	productBOMSheet := xlFile.Sheets[0]

	if productBOMSheet == nil {
		return c.error("未找到产品BOM导入文件")
	}

	if productBOMSheet.Rows == nil {
		return c.error("产品BOM导入内容格式错误")
	}

	rowTitle := productBOMSheet.Rows[0]
	if rowTitle == nil || rowTitle.Cells == nil || rowTitle.Cells[0].Value!= "成品货号" {
		return c.error("未找到产品BOM导入文件")
	}

	var productBOMExcelList []model.ProductBOM
	for _, row := range productBOMSheet.Rows[1:] {
		var productBOM model.ProductBOM
		if row.Cells == nil || row.Cells[0].Value == "" {
			continue
		}
		if len(row.Cells) < 5 {
			continue
		}
		productCode := row.Cells[0].Value
		if _, ok := productMap[productCode]; !ok {
			continue
		}
		productId := productMap[productCode].ID
		if _,ok := productBOMMap[productId]; ok {
			if err := c.db().Where("product_id =?", productId).Delete(model.ProductBOM{}).Error; err != nil {
				c.log(err.Error())
				return c.error("删除失败")
			}
			delete(productBOMMap, productId)
		}
		productBOM.ProductID = productId
		productBOM.PartID = partMap[row.Cells[2].Value].ID
		productBOM.PartQuantity, _ = strconv.Atoi(row.Cells[4].Value)
		productBOM.CreateBy = "Admin"
		productBOM.CreateTime = time.Now().Format("2006-01-02 15:04:05")
		productBOMExcelList = append(productBOMExcelList, productBOM)
	}
	log.Info("Import ProductBOM productBOMExcelList Len: " ,len(productBOMExcelList))
	if err := c.db().Create(&productBOMExcelList).Error; err != nil {
		c.log(err.Error())
		return c.error("添加失败")
	}
	return c.success(nil)
}


func (c *ProductBOM) DownloadTemplate() Res {
	log.Info("Download ProductBOM Template")
	file := xlsx.NewFile()
	sheet, err := file.AddSheet("产品BOM表导入模板")
	if err != nil {
		log.Error("DownloadProductBOMTemplate Error:", err)
		return c.error("下载模板失败")
	}

	rowTitle := sheet.AddRow()
	cellProductCode := rowTitle.AddCell()
	cellProductCode.Value = "成品货号"
	cellProductSku := rowTitle.AddCell()
	cellProductSku.Value = "成品SKU"
	cellPartCode := rowTitle.AddCell()
	cellPartCode.Value = "零件货号"
	cellSkuName := rowTitle.AddCell()
	cellSkuName.Value = "零件SKU"
	cellPartQuantity := rowTitle.AddCell()
	cellPartQuantity.Value = "数量"

	appPath := c.pathExist(c.getAppPath() + "/outputFile")
	log.Info("appPath: ", appPath)
	errSave := file.Save(appPath + "/产品BOM导入模板.xlsx")
	if errSave!= nil {
		log.Error("DownloadProductBOMTemplate Save Error:", errSave)
		return c.error("下载模板失败")
	}
	return c.success(nil)
}